<?php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage;

/**
 * Class Http
 * 2019-05-24
 */
class Http
{
	protected $request;

	protected $cookie;

	protected static $session;

	public function __construct()
	{
		$this->request = Request::createFromGlobals();
	}

	/**
	 * 返回一个 Request 对象
	 * @return Request
	 */
	public function request()
	{
		return $this->request;
	}

	/**
	 * 返回一个 Response 对象
	 * @param mixed $content: 内容，可以是任何类型的数据
	 * @return Response
	 */
	public function response($content = null)
	{
		$toJson = false;
		$response = new Response();
		if (!is_null($content)) {
			if (is_array($content) || is_object($content)) {
				$toJson = true;
				$content = json_encode($content);
			}
			if (!is_string($content)) {
				$content = var_export($content, true);
			}
			$response->setContent($content);
			$response->setCharset('utf-8');
			if ($toJson) {
				$response->headers->set('Content-Type', 'application/json');
			}
		}
		return $response;
	}

	/**
	 * 请求 API 的 Options
	 * @param array $config
	 * @return array
	 */
	public function apiRequestOptions($config = [])
	{
		$config = $config ? $config : get_config();
		$client_ip = $this->request()->getClientIp();
		$options = [
			'headers' => [
				'X-APPID' => $config["app_id"],
				'Accept' => 'application/json',
				'X-USER-IP' => $client_ip,
				'CLIENT-IP' => $client_ip,
				'X-FORWARDED-FOR' => $client_ip,
				'Cookie' => null,
				'User-Agent' => $this->request()->headers->get("user-agent"),
			],
		];
		if( $bearer = is_login() ) {
			$options['headers']['Authorization'] = $bearer;
		}
		return $options;
	}

	/**
	 * 创建一个 json Response 对象
	 * @param mixed $data: 内容，可以是任何类型的数据，这里会把它包装成 API 接口并 json_encode
	 * @param int $code
	 * @param string $message
	 * @param bool $key_to_hump
	 * @param bool $jsonp_callback
	 * @return Response
	 */
	public function apiResponse($data = null, $code=1, $message='', $key_to_hump = true, $jsonp_callback = null)
	{
		if(is_null($data)) {
			$data = "";
		}
		if($key_to_hump && (is_array($data) || is_object($data)) && function_exists("key_to_hump")) {
			$data = key_to_hump($data, false); //转为驼峰式
		}
		$return = json_encode([ 'code'=>$code, 'message'=>$message, 'data'=>$data], JSON_UNESCAPED_UNICODE);
		if($jsonp_callback) {
			$return = $jsonp_callback .'('. $return .')';
		}
		$return = str_ireplace(':null', ':""', $return);
		$response = new Response();
		$response = $this->cors($response);
		$response->setContent($return);
		$response->setCharset('utf-8');
		$response->headers->set('Content-Type', 'application/json');
		return $response;
	}

	/**
	 * 返回 GET 数据
	 * @param string $key
	 * @param string $default
	 * @return array|mixed
	 */
	public function get($key = null, $default = null)
	{
		if (is_null($key)) {
			return $this->request->query->all();
		}
		return $this->request->query->get($key, $default);
	}

	/**
	 * 返回 POST 数据
	 * @param string $key
	 * @param string $default
	 * @return array|mixed
	 */
	public function post($key = null, $default = null)
	{
		if (is_null($key)) {
			return $this->request->request->all();
		}
		return $this->request->request->get($key, $default);
	}

	/**
	 * 先取 POST，再取 GET，相同的键采取 GET
	 * @param null $key
	 * @param null $default
	 * @return array
	 */
	public function postGet($key = null, $default = null)
	{
		if (is_null($key)) {
			$get = $this->request->query->all();
			$post = $this->request->request->all();
			return array_merge($post, $get);
		}
		else {
			$get = $this->request->query->get($key, $default);
			$post = $this->request->request->get($key, $default);
			return !is_null($get) ? $get : $post;
		}
	}

	/**
	 * 先取 GET，再取 POST，相同的键采取 POST
	 * @param null $key
	 * @param null $default
	 * @return array|mixed
	 */
	public function getPost($key = null, $default = null)
	{
		if (is_null($key)) {
			$get = $this->request->query->all();
			$post = $this->request->request->all();
			return array_merge($get, $post);
		}
		else {
			$get = $this->request->query->get($key, $default);
			$post = $this->request->request->get($key, $default);
			return !is_null($post) ? $post : $get;
		}
	}

	public function newCookie($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null)
	{
		$cookie = new Cookie($name, $value, $expire, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
		return $cookie;
	}

	/**
	 * 获取 Session 实例 并启动
	 * @return Session
	 */
	public function session()
	{
		if (!self::$session) {
			$options = array(
				'name' => 'PHPSESSID'. strtoupper(get_config('php_env')[0]),
				'gc_maxlifetime' => 10800,
				'cookie_domain' => get_config('cookie_domain'),
				'cookie_lifetime' => get_config('cookie_lifetime', 10800),
			);
			$handler = null;
			$storage = new Storage\NativeSessionStorage($options, $handler);
			self::$session = new Session($storage);
		}
		if (!self::$session->getId()) {
			self::$session->start();
		}

		return self::$session;
	}

	/**
	 * 设置跨域
	 * @param Response $response
	 * @return Response
	 */
	public function cors(Response $response = null)
	{
		if (is_null($response) || !$response instanceof Response) {
			$response = new Response();
		}

		$response->headers->set('Access-Control-Allow-Origin', '*');
		$response->headers->set('Access-Control-Allow-Headers', '*');
		$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

		if($this->request()->getMethod() == 'OPTIONS') {
			$response->setStatusCode(204);
			$response->send();
			exit;
		}
		return $response;
	}


	/**
	 * 测试 request 信息
	 */
	public function requestTest()
	{
		$request = $this->request;

		$data["method"] = $request->getMethod();						// GET、POST、OPTIONS 等等

		$data["get"] = $request->query->all();							// 相当于 $_GET
		$data["post"] = $request->request->all();						// 相当于 $_POST

		$data["request_content"] = $request->getContent();				// 连同 request body 一起被发送来的原始数据（raw data），如：name=ccc&age=30

		$data["ip"] = $request->getClientIp();
		$data["host"] = $request->headers->get("host");				// 如：test.com
		$data["scheme"] = $request->getScheme();							// 如：http、https
		$data["scheme_host"] = $request->getSchemeAndHttpHost();			// 如：http://test.com

		$data["path_info"] = $request->getPathInfo();						// 如：/test/a
		$data["query_string"] = $request->server->get("QUERY_STRING");	// 如：name=aaa&age=20
		$data["request_uri"] = $request->server->get("REQUEST_URI");	// 如：/test/a?name=aaa&age=20
		$data["content_type"] = $request->server->get("CONTENT_TYPE");	// 如：application/x-www-form-urlencoded

		$data["user_agent"] = $request->headers->get("user-agent");

//		$data["headers"] = $request->headers->all();
//		$data["cookies"] = $request->cookies->all();

//		put_file_contents($data, "requestTest");

		$response = $this->apiResponse($data);

		//$testCookieName = "test_cookie";
		//$testCookieData = date("H.i.s");
		//if (!$request->cookies->get($testCookieName)) {
		//	$response->headers->setCookie($this->newCookie($testCookieName, $testCookieData, time()+5));
		//}

		$response->send();
	}
}
